package net.gdface.facelog;

import static com.google.common.base.Preconditions.checkArgument;

import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.google.common.base.Joiner;
import com.google.common.base.MoreObjects;
import com.google.common.collect.Lists;

import gu.simplemq.redis.JedisUtils;
import gu.simplemq.redis.JedisPoolLazy.PropName;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Protocol;

/**
 * 本地redis服务控制器<br>
 * 如果redis指定为本机服务，则尝试连接，连接不上则尝试启动
 * @author guyadong
 *
 */
class RedisController extends BaseServiceController {
	/** redis数据库配置参数 */
	private final Map<PropName, Object> parameters;
	/**
	 * 构造方法
	 * @param parameters redis连接参数
	 */
	RedisController(Map<PropName, Object> parameters) {
		super();
		this.parameters = parameters;
		location = JedisUtils.getCanonicalURI(parameters);
		waitIfAbsent = CONFIG.getBoolean(REDIS_WAITIFABSENT,false);
		tryCountLimit = CONFIG.getInt(REDIS_TRYCOUNT,DEFAULT_TRY_COUNT);
		tryInterval = CONFIG.getLong(REDIS_TRYINTERVAL,DEFAULT_TRY_INTERVAL);
	}
	@Override
	protected boolean testConnect(){
		return JedisUtils.testConnect(parameters);
	}
	@Override
	protected boolean canStartLocal(){
		return CONFIG.containsKey(REDIS_EXE);
	}
	/** 启动本地 redis 服务器 
	 * @return redis server 进程对象，{@link Process}
	 */
	@Override
	protected Process startLocalServer(){
		String redisExe = CONFIG.getString(REDIS_EXE,"");
		checkArgument(!redisExe.isEmpty(),"NOT DEFINE(参数没有定义) %s",REDIS_EXE);

		ArrayList<String> args = Lists.newArrayList(redisExe);
		// 命令行指定端口
		if(parameters.containsKey(PropName.port)){
			args.add("--port");
			args.add(Integer.toString((Integer) parameters.get(PropName.port)));
		}
		// 命令行指定password
		if(parameters.containsKey(PropName.password)){
			args.add("--requirepass");
			args.add((String) parameters.get(PropName.password));
		}
		try {
			logger.info("start redis server(启动redis服务器) {}",MoreObjects.firstNonNull( parameters.get(PropName.port), Protocol.DEFAULT_PORT));
			
			String cmd = Joiner.on(' ').join(args);
			logger.debug("cmd(启动命令): {}",cmd);
			return new ProcessBuilder(args)
					.redirectError(Redirect.INHERIT)
					.redirectOutput(Redirect.INHERIT)
					.start();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}	
	}
	/** 中止本地 redis 服务器*/
	@Override
	protected void  shutdownLocalServer(){
		if(process != null){
			synchronized (this) {
				if(process != null){
					logger.info("shutdown redis server(关闭redis服务器)");
					HashMap<PropName, Object> param = JedisUtils.initParameters(parameters);
					Jedis jedis = new Jedis(JedisUtils.getCanonicalURI(param));
					try{
						jedis.shutdown();
					}finally{
						jedis.close();
					}
					process = null;
				}
			}
		}
	}
	@Override
	protected boolean isEmbedded() {
		return false;
	}

}
